﻿using LunchList.Controllers;
using LunchList.ViewModels;
using LunchListCore.Entities;
using LunchListCore.Interfaces.Agents;
using LunchListCore.Interfaces.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace LunchList.Tests
{
    [TestClass]
    public class EventsControllerTests
    {
        [TestMethod]
        public void EventsIndexTest()
        {
            IList<IGuest> guests = new List<IGuest>()
			{
				new Guest()
				{
					AdUserId = "NATest",
                    Name = "TestUserName",
					GuestId = 1
				}
			};
            IList<IEvent> eventsToReturn = new List<IEvent>();

            eventsToReturn.Add(new Event() 
            {
                EventName = "Red Robins",
                EventDate = new DateTime(2014, 3, 28)
            });

            eventsToReturn.Add(new Event()
            {
                EventName = "TGI Fridays",
                EventDate = new DateTime(2014, 2, 27)
            });

            DateTime? eventDate = null;

            Mock<ILunchAgent> mockLunchAgent = new Mock<ILunchAgent>();
            mockLunchAgent.Setup(x => x.GetEvents(eventDate)).Returns(() => eventsToReturn);

            EventsController eventsController = new EventsController();
            eventsController.LunchAgent = mockLunchAgent.Object;

            Mock<IGuestContext> mockGuestContext = new Mock<IGuestContext>();
            mockGuestContext.Setup(x => x.User).Returns(() => guests[0]);
            eventsController.GuestContext = mockGuestContext.Object;

            ViewResult viewResult = eventsController.Index() as ViewResult;
            Assert.IsNotNull(viewResult, "The result is not a view result");
        }

        [TestMethod]
        public void GetEventsListTest()
        {
            Mock<ILunchAgent> mockLunchAgent = new Mock<ILunchAgent>();

            IList<IGuest> guests = new List<IGuest>()
			{
				new Guest()
				{
					AdUserId = "NATest",
                    Name = "TestUserName",
					GuestId = 1
				}
			};

            IList<IEvent> eventsToReturn = new List<IEvent>
                {
                    new Event()
                    {
                        EventName = "Red Robins",
                        EventDate = new DateTime(2014, 3, 28)
                    },
                    new Event()
                    {
                        EventName = "TGI Fridays",
                        EventDate = new DateTime(2014, 2, 27)
                    }
                };
                

            DateTime? eventDate = null;
            mockLunchAgent.Setup(x => x.GetEvents(eventDate)).Returns(() => eventsToReturn);

            Mock<IGuestContext> mockGuestContext = new Mock<IGuestContext>();
            mockGuestContext.Setup(x => x.User).Returns(() => guests[0]);
            

            EventsController eventsController = new EventsController();
            eventsController.LunchAgent = mockLunchAgent.Object;
            eventsController.GuestContext = mockGuestContext.Object;

            PartialViewResult viewResult = eventsController.GetEventList() as PartialViewResult;
            
            Assert.IsNotNull(viewResult, "The result is not a view result");
        }

        [TestMethod]
        public void GetEventsList_returns_ErrorDisplayView_onException_Test()
        {
            DateTime? eventDate = null;

            Mock<ILunchAgent> mockLunchAgent = new Mock<ILunchAgent>();
            mockLunchAgent.Setup(x => x.GetEvents(eventDate)).Returns(() => null);

            EventsController eventsController = new EventsController();
            eventsController.LunchAgent = mockLunchAgent.Object;

            Mock<IGuestContext> mockGuestContext = new Mock<IGuestContext>();
            mockGuestContext.Setup(x => x.User).Returns(() => null);
            eventsController.GuestContext = mockGuestContext.Object;

            PartialViewResult viewResult = eventsController.GetEventList() as PartialViewResult;

            Assert.AreEqual("_ErrorDisplay", viewResult.ViewName);
        }

        [TestMethod]
        public void AddEventTest()
        {
			EventsViewModel mockEventsViewModel = new EventsViewModel();
            mockEventsViewModel.EventName = "Test Event";
            mockEventsViewModel.EventDate = DateTime.Today;

            IList<IGuest> guests = new List<IGuest>()
			{
				new Guest()
				{                    
					AdUserId = "NATest",
                    Name = "TestUserName",
					GuestId = 1
				}
			};

            Mock<IGuestContext> mockGuestContext = new Mock<IGuestContext>();
            mockGuestContext.Setup(x => x.User).Returns(() => guests[0]);

            IList<IEvent> eventsToReturn = new List<IEvent>
                {                    
                    new Event()
                    {
                        EventName = "Test Event",
                        EventDate = DateTime.Today
                    }
                };

            Mock<ILunchAgent> mockLunchAgent = new Mock<ILunchAgent>();
            DateTime? eventDate = null;
            mockLunchAgent.Setup(x => x.GetEvents(eventDate)).Returns(() => eventsToReturn);
            mockLunchAgent.Setup(x => x.AddEvent(mockEventsViewModel.EventName, mockEventsViewModel.EventDate, null, "")).Returns(() => null);


            EventsController eventsController = new EventsController();
            eventsController.GuestContext = mockGuestContext.Object;
            eventsController.LunchAgent = mockLunchAgent.Object;

            PartialViewResult viewResult = eventsController.AddEvent(mockEventsViewModel) as PartialViewResult;

            //Assert.IsInstanceOfType(viewResult, typeof(PartialViewResult));
            Assert.AreEqual("_EventList", viewResult.ViewName);
            Assert.IsNotNull(viewResult);
            mockLunchAgent.Verify(x => x.GetEvents(eventDate),Times.Once);
            mockLunchAgent.Verify(x => x.AddEvent(It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<IGuestId>(), It.IsAny<string>()), Times.Once);
        }

        [TestMethod]
        public void DeleteEventValidTest()
        {
            //Mock<IGuestContext> mockGuestContext = new Mock<IGuestContext>();
            //mockGuestContext.Setup(x => x.User).Returns(() => new Guest()
            //                                                    {
            //                                                        AdUserId = "NATest",
            //                                                        Name = "TestUserName",
            //                                                        GuestId = 1
            //                                                    });

            //Mock<ILunchAgent> mockLunchAgent = new Mock<ILunchAgent>();
            //DateTime? eventDate = null;
            //mockLunchAgent.Setup(x => x.GetEvents(eventDate)).Returns(() => new List<IEvent>
            //                                                                {                    
            //                                                                    new Event()
            //                                                                    {
            //                                                                        EventName = "Test Event",
            //                                                                        EventDate = DateTime.Today
            //                                                                    }
            //                                                                });

            //mockLunchAgent.Setup(x => x.DeleteEvent(It.IsAny<int>())).Returns(true);

            //EventsController eventsController = new EventsController();
            //eventsController.GuestContext = mockGuestContext.Object;
            //eventsController.LunchAgent = mockLunchAgent.Object;
        }
    }
}
